iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
自我挑戰組

模仿知名網站的外觀系列 第 9

【Day9】模仿知名網站的外觀 Instagram(9) 編寫Comment區塊-2

  • 分享至 

  • xImage
  •  

上一回我們幾乎完成了Comment區塊,這一次我們將完成剩下的部分,同樣從PostCard.jsx複製程式碼,修改後ModalBody的內容如下:

<div className="flex h-[75vh]">
	<div className="w-[45%] flex flex-col justify-center">
		<img
			className="max-h-full w-full"
			src="https://images.pexels.com/photos/18111153/pexels-photo-18111153.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
			alt=""
		/>
	</div>
	<div className="w-[55%] pl-10">
		<div className="flex justify-between items-center py-5">
			<div className="flex items-center">
				<div>
					<img
						className="w-9 h-9 rounded-full"
						src="https://images.pexels.com/photos/17857033/pexels-photo-17857033.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
						alt=""
					/>
				</div>
				<div className="ml-2">
					<p>username</p>
				</div>
			</div>

			<BsThreeDots />
		</div>
		<hr />
		<div>
			{[1, 1, 1].map(() => (
				<CommentCard />
			))}
		</div>

		<div className="flex justify-between items-center w-full py-4">
			<div className="flex items-center space-x-2">
				{isPostLiked ? (
					<AiFillHeart
						className="text-2xl hover:opacity-50 cursor-pointer text-red-600"
						onClick={() => handlePostLike()}
					/>
				) : (
					<AiOutlineHeart
						className="text-2xl hover:opacity-50 cursor-pointer"
						onClick={() => handlePostLike()}
					/>
				)}

				<FaRegComment className="text-xl hover:opacity-50 cursor-pointer" />
				<IoPaperPlaneOutline className="text-xl hover:opacity-50 cursor-pointer" />
			</div>

			<div className="cursor-pointer">
				{isPostSaved ? (
					<BsBookmarkFill
						onClick={() => handlePostSave()}
						className="text-xl hover:opacity-50 cursor-pointer"
					/>
				) : (
					<BsBookmark
						onClick={() => handlePostSave()}
						className="text-xl hover:opacity-50 cursor-pointer"
					/>
				)}
			</div>
		</div>

		<div className="w-full py-2">
			<p>11 likes</p>
			<p className="opacity-50 text-sm">1 DAY AGO</p>
		</div>

		<div className="w-full">
			<div className="flex w-full items-center">
				<BsEmojiSmile />
				<input
					className="commentInput"
					type="text"
					placeholder="Add a comment..."
				/>
			</div>
		</div>
	</div>
</div>

我們快完成了,只需要在做些排版設定。

Untitled

在Comment資料夾下,新增CommentModal.css。

.comment{
    max-height: 45vh;
    overflow-y: scroll;
}

.comment::-webkit-scrollbar{
    display: none;
}

.commentInput{
    border: none;
    outline: none;
    padding: 5px;
}

調整CommentModal.jsx的一些細節部分的排版。

import { Modal, ModalBody, ModalContent, ModalOverlay } from "@chakra-ui/react";
import React from "react";
import CommentCard from "./CommentCard";
import {
	BsBookmark,
	BsBookmarkFill,
	BsThreeDots,
	BsEmojiSmile,
} from "react-icons/bs";
import { AiFillHeart, AiOutlineHeart } from "react-icons/ai";
import { FaRegComment } from "react-icons/fa";
import { IoPaperPlaneOutline } from "react-icons/io5";
import "./CommentModal.css";

const CommentModal = ({
	onClose,
	isOpen,
	isPostLiked,
	isPostSaved,
	handlePostLike,
	handlePostSave,
}) => {
	return (
		<div>
			<Modal size={"4xl"} onClose={onClose} isOpen={true} isCentered>
				<ModalOverlay />
				<ModalContent>
					<ModalBody>
						<div className="flex h-[75vh]">
							<div className="w-[45%] flex flex-col justify-center">
								<img
									className="max-h-full w-full"
									src="https://images.pexels.com/photos/18111153/pexels-photo-18111153.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
									alt=""
								/>
							</div>
							<div className="w-[55%] pl-10 relative">
								<div className="flex justify-between items-center py-5">
									<div className="flex items-center">
										<div>
											<img
												className="w-9 h-9 rounded-full"
												src="https://images.pexels.com/photos/17857033/pexels-photo-17857033.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
												alt=""
											/>
										</div>
										<div className="ml-2">
											<p>username</p>
										</div>
									</div>

									<BsThreeDots />
								</div>
								<hr />
								<div className="comment">
									{[1, 1, 1].map(() => (
										<CommentCard />
									))}
								</div>

								<div className="absolute bottom-0 w-[90%]">
									<div className="flex justify-between items-center w-full py-4">
										<div className="flex items-center space-x-2">
											{isPostLiked ? (
												<AiFillHeart
													className="text-2xl hover:opacity-50 cursor-pointer text-red-600"
													onClick={() => handlePostLike()}
												/>
											) : (
												<AiOutlineHeart
													className="text-2xl hover:opacity-50 cursor-pointer"
													onClick={() => handlePostLike()}
												/>
											)}

											<FaRegComment className="text-xl hover:opacity-50 cursor-pointer" />
											<IoPaperPlaneOutline className="text-xl hover:opacity-50 cursor-pointer" />
										</div>

										<div className="cursor-pointer">
											{isPostSaved ? (
												<BsBookmarkFill
													onClick={() => handlePostSave()}
													className="text-xl hover:opacity-50 cursor-pointer"
												/>
											) : (
												<BsBookmark
													onClick={() => handlePostSave()}
													className="text-xl hover:opacity-50 cursor-pointer"
												/>
											)}
										</div>
									</div>

									<div className="w-full py-2">
										<p>11 likes</p>
										<p className="opacity-50 text-sm">1 DAY AGO</p>
									</div>

									<div className="flex w-full items-center border-t">
										<BsEmojiSmile />
										<input
											className="commentInput"
											type="text"
											placeholder="Add a comment..."
										/>
									</div>
								</div>
							</div>
						</div>
					</ModalBody>
				</ModalContent>
			</Modal>
		</div>
	);
};

export default CommentModal;

我們的Comment區塊就編寫好了,不過一開啟專案就顯示Comment區塊是錯誤的,應該要按下按鈕後再彈出Comment才對,而且我們也關不掉Comment區塊。

我們將CommentModal.jsx做一些處理,讓Comment區塊不會自己彈出,對Modal做修改。

修改後的結果如下:

<Modal size={"4xl"} onClose={onClose} isOpen={isOpen} isCentered>

將true改成isOpen,現在不會自動出現Comment視窗了。

我們先回到PostCard.jsx,處理按下Comment按鈕時如何跳出Comment視窗,以及傳入的參數。

修改完成的PostCard.jsx如下:

import React, { useState } from "react";
import {
	BsBookmark,
	BsBookmarkFill,
	BsThreeDots,
	BsEmojiSmile,
} from "react-icons/bs";
import { AiFillHeart, AiOutlineHeart } from "react-icons/ai";
import { FaRegComment } from "react-icons/fa";
import { IoPaperPlaneOutline } from "react-icons/io5";
import "./PostCard.css";
import CommentModal from "../Comment/CommentModal";
import { useDisclosure } from "@chakra-ui/react";

const PostCard = () => {
	const [showDropDown, setShowDropDown] = useState(false);
	const [isPostLiked, setIsPostLiked] = useState(false);
	const [isPostSaved, setIsPostSaved] = useState(false);
	const { isOpen, onOpen, onClose } = useDisclosure()

	const handlePostSave = () => {
		setIsPostSaved(!isPostSaved);
	};

	const handlePostLike = () => {
		setIsPostLiked(!isPostLiked);
	};

	const handleClick = () => {
		setShowDropDown(!showDropDown);
	};

	const handleOpenCommentModal = () => {
		onOpen()
	}

	return (
		<div>
			<div className="border rounded-md w-full">
				<div className="flex justify-between items-center w-full py-4 px-5">
					<div className="flex items-center">
						<img
							className="h-12 w-12 rounded-full"
							src="https://images.pexels.com/photos/18048873/pexels-photo-18048873/free-photo-of-4k.jpeg?auto=compress"
							alt=""
						/>
						<div className="pl-2">
							<p className="font-semibold text-sm">username</p>
							<p className="font-thin text-sm">location</p>
						</div>
					</div>
					<div className="dropdown">
						<BsThreeDots className="dots" onClick={() => handleClick()} />
						{showDropDown && (
							<p className="bg-black text-white py-1 px-4 rounded-md cursor-pointer">
								Report
							</p>
						)}
					</div>
				</div>

				<div className="w-full">
					<img className="w-full" src="https://images.pexels.com/photos/18111496/pexels-photo-18111496.jpeg?auto=compress&cs=tinysrgb&w=468&h=585" alt="" />
				</div>

				<div className="flex justify-between items-center w-full px-5 py-4">
					<div className="flex items-center space-x-2">
						{isPostLiked ? (
							<AiFillHeart
								className="text-2xl hover:opacity-50 cursor-pointer text-red-600"
								onClick={() => handlePostLike()}
							/>
						) : (
							<AiOutlineHeart
								className="text-2xl hover:opacity-50 cursor-pointer"
								onClick={() => handlePostLike()}
							/>
						)}

						<FaRegComment onClick={() => handleOpenCommentModal()} className="text-xl hover:opacity-50 cursor-pointer" />
						<IoPaperPlaneOutline className="text-xl hover:opacity-50 cursor-pointer" />
					</div>

					<div className="cursor-pointer">
						{isPostSaved ? (
							<BsBookmarkFill
								onClick={() => handlePostSave()}
								className="text-xl hover:opacity-50 cursor-pointer"
							/>
						) : (
							<BsBookmark
								onClick={() => handlePostSave()}
								className="text-xl hover:opacity-50 cursor-pointer"
							/>
						)}
					</div>
				</div>

				<div className="w-full py-2 px-5">
					<p>11 likes</p>
					<p className="opacity-50 py-2 cursor-pointer">view all 45 comments</p>
				</div>

				<div className="w-full">
					<div className="flex w-full items-center px-5">
						<input
							className="commentInput"
							type="text"
							placeholder="Add a comment..."
						/>
						<BsEmojiSmile />
					</div>
				</div>
			</div>
			<CommentModal onClose={onClose} isOpen={isOpen} isPostLiked={isPostLiked} isPostSaved={isPostSaved} handlePostLike={handlePostLike} handlePostSave={handlePostSave}/>
		</div>
	);
};

export default PostCard;

多了兩個const宣告,FaRegComment有了onClick,CommentModal設定傳入的參數。

我們的專案目前的是這樣的,按Comment的icon就能顯示Comment,點周圍的灰色部分就能離開Comment。

在首頁按愛心,Comment視窗也會顯示,如果在Comment視窗取消愛心,首頁的愛心也會消失,首頁的愛心、書籤和Comment區塊是聯動的。

Untitled

我們的首頁離完成只差一點了,接著是HomeRight區塊,來到HomeRight.jsx。

進行修改:

import React from "react";

const HomeRight = () => {
	return (
		<div className="border">
			<div>
				<div>
					<div className="flex items-center">
						<img
							className="w-12 h-12 rounded-full"
							src="https://images.pexels.com/photos/18111088/pexels-photo-18111088.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
							alt=""
						/>
						<div className="ml-3">
							<p>FullName</p>
							<p className="opacity-70">username</p>
						</div>
					</div>
				</div>
			</div>
		</div>
	);
};

export default HomeRight;

完成一小部分的HomeRight。

Untitled

在HomeRight資料夾下,新增SuggestionCard.jsx,這是用來處理推薦的用戶。

import React from "react";

const SuggestionCard = () => {
	return (
		<div className="flex justify-between items-center">
			<div className="flex items-center">
				<img
					className="w-9 h-9 rounded-full"
					src="https://images.pexels.com/photos/18171438/pexels-photo-18171438.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
					alt=""
				/>
				<div className="ml-2">
					<p className="text-sm font-semibold">username</p>
					<p className="text-sm font-semibold opacity-70">Follows you</p>
				</div>
			</div>
			<p className="text-blue-700 text-sm font-semibold">Follow</p>
		</div>
	);
};

export default SuggestionCard;

修改HomeRight.jsx,顯示SuggestionCard,以及調整CSS內容。

import React from "react";
import SuggestionCard from "./SuggestionCard";

const HomeRight = () => {
	return (
		<div>
			<div>
				<div className="flex justify-between items-center">
					<div className="flex items-center">
						<div>
							<img
								className="w-12 h-12 rounded-full"
								src="https://images.pexels.com/photos/18111088/pexels-photo-18111088.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"
								alt=""
							/>
						</div>
						<div className="ml-3">
							<p>FullName</p>
							<p className="opacity-70">username</p>
						</div>
					</div>

					<div>
						<p className="text-blue-700 font-semibold">Switch</p>
					</div>
				</div>
				<div className="space-y-5 mt-10">
					{[1, 1, 1, 1, 1].map((item) => (
						<SuggestionCard />
					))}
				</div>
			</div>
		</div>
	);
};

export default HomeRight;

我們的首頁就完成了。

Untitled


上一篇
【Day8】模仿知名網站的外觀 Instagram(8) 編寫Comment區塊
下一篇
【Day10】模仿知名網站的外觀 Instagram(10) 建立新貼文
系列文
模仿知名網站的外觀30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言